package net.pulseproject.commons.midi;

import java.util.Date;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.MidiDevice.Info;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MidiSystemStaticWrapper implements MidiSystem {

	private static final Log LOG = LogFactory.getLog(MidiSystemStaticWrapper.class);
	
	@Override
	public final MidiDevice getMidiDevice(final Info info) {
		LOG.info("getMidiDevice(info=" + info + ")");
		if(info == null) { throw new IllegalArgumentException("info == null"); }
		
		try {
			return javax.sound.midi.MidiSystem.getMidiDevice(info);
		} catch (final MidiUnavailableException e) {
			throw new RuntimeException("Could not get MIDI device info for port [" + info.getName() + "]!", e);
		}
	}

	@Override
	public final Info[] listMidiDeviceInfos() {
		LOG.info("listMidiDeviceInfos()");
		
		final Date startDate = new Date();
		// FIXME BUG threw exception in javax.MidiSystem.getMidiDeviceInfo() !!! (see exception stacktrace down below)
		final Info[] infos = javax.sound.midi.MidiSystem.getMidiDeviceInfo();
		
		final long milliSecondsNeeded = new Date().getTime() - startDate.getTime();
		final double secondsNeeded = milliSecondsNeeded / 1000.0;
		LOG.debug("listMidiDeviceInfos() ... returning " + infos.length + " infos took " + secondsNeeded + " seconds.");
		
		
		return infos;
	}

//	2011-03-03 22:49:26,663 [INFO ] net.pulseproject.mkinector.debugapp.MkinectorDebugApp - startUp()
//	2011-03-03 22:49:28,453 [DEBUG] net.pulseproject.josceleton.Josceleton - openConnection()
//	2011-03-03 22:49:28,453 [DEBUG] net.pulseproject.josceleton.Josceleton - initIfNecessary() ... creating josceleton guice modules
//	2011-03-03 22:49:28,633 [DEBUG] net.pulseproject.josceleton.core.internal.apiimpl.JosceletonConnectorImpl - openConnection()
//	2011-03-03 22:49:28,633 [DEBUG] net.pulseproject.josceleton.core.internal.apiimpl.JosceletonConnectorImpl - openConnectionOnPort(port=7110)
//	2011-03-03 22:49:28,634 [DEBUG] net.pulseproject.josceleton.core.internal.logic.OscPortConnectorImpl - connect(port=7110)
//	2011-03-03 22:49:28,667 [DEBUG] net.pulseproject.josceleton.core.internal.logic.OscPortConnectionImpl - addListenerForAddress(adressType=AddressType[value=/joint, userMessageType=null], listener=net.pulseproject.josceleton.core.internal.logic.OsceletonLiveMessageTransformerImpl@7182c2d9)
//	2011-03-03 22:49:28,668 [DEBUG] net.pulseproject.josceleton.core.internal.logic.OscPortConnectionImpl - addListenerForAddress(adressType=AddressType[value=/new_user, userMessageType=NEW_USER], listener=net.pulseproject.josceleton.core.internal.logic.OsceletonLiveMessageTransformerImpl@7182c2d9)
//	2011-03-03 22:49:28,668 [DEBUG] net.pulseproject.josceleton.core.internal.logic.OscPortConnectionImpl - addListenerForAddress(adressType=AddressType[value=/new_skel, userMessageType=NEW_SKEL], listener=net.pulseproject.josceleton.core.internal.logic.OsceletonLiveMessageTransformerImpl@7182c2d9)
//	2011-03-03 22:49:28,668 [DEBUG] net.pulseproject.josceleton.core.internal.logic.OscPortConnectionImpl - addListenerForAddress(adressType=AddressType[value=/lost_user, userMessageType=LOST_USER], listener=net.pulseproject.josceleton.core.internal.logic.OsceletonLiveMessageTransformerImpl@7182c2d9)
//	2011-03-03 22:49:28,674 [INFO ] net.pulseproject.mkinector.debugapp.scenario1.Scenario1 - registerGestures(..)
//	2011-03-03 22:49:28,681 [DEBUG] net.pulseproject.mkinector.josceleton.gesture.internal.HitWallGestureImpl - new HitWallGesture(filterer, jointType=BodyPart[id=l_hand], xyzDirection=Z, triggerValue=[0.9], checkTriggerForHigher=false) ... triggerValueDeviation=[0.92]
//	2011-03-03 22:49:28,682 [DEBUG] net.pulseproject.mkinector.josceleton.gesture.internal.HitWallGestureImpl - new HitWallGesture(filterer, jointType=BodyPart[id=r_hand], xyzDirection=Z, triggerValue=[0.9], checkTriggerForHigher=false) ... triggerValueDeviation=[0.92]
//	2011-03-03 22:49:32,515 [DEBUG] net.pulseproject.josceleton.core.internal.UserManagerImpl - forUserMessage(userId=1, type=NEW_USER)
//	2011-03-03 22:49:32,515 [DEBUG] net.pulseproject.josceleton.core.internal.UserManagerImpl - createNewUser(1)
//	2011-03-03 22:49:32,518 [INFO ] net.pulseproject.mkinector.debugapp.misc.OscConnectionWindowGlue - onUserWaiting(user=UserImpl[id=1, uniqueId=0])
//	2011-03-03 22:49:32,518 [DEBUG] net.pulseproject.mkinector.debugapp.misc.OscConnectionWindowGlue - doAddUser(user=UserImpl[id=1, uniqueId=0])
//	2011-03-03 22:49:32,612 [DEBUG] net.pulseproject.mkinector.debugapp.view.UserPanelsWrapper - onAddUserPanel(userPanel)
//	2011-03-03 22:49:38,489 [DEBUG] net.pulseproject.josceleton.core.internal.UserManagerImpl - forUserMessage(userId=2, type=NEW_USER)
//	2011-03-03 22:49:38,490 [DEBUG] net.pulseproject.josceleton.core.internal.UserManagerImpl - createNewUser(2)
//	2011-03-03 22:49:38,490 [INFO ] net.pulseproject.mkinector.debugapp.misc.OscConnectionWindowGlue - onUserWaiting(user=UserImpl[id=2, uniqueId=1])
//	2011-03-03 22:49:38,490 [DEBUG] net.pulseproject.mkinector.debugapp.misc.OscConnectionWindowGlue - doAddUser(user=UserImpl[id=2, uniqueId=1])
//	2011-03-03 22:49:38,539 [DEBUG] net.pulseproject.mkinector.debugapp.view.UserPanelsWrapper - onAddUserPanel(userPanel)
//	2011-03-03 22:49:49,497 [DEBUG] net.pulseproject.josceleton.core.internal.UserManagerImpl - forUserMessage(userId=1, type=NEW_SKEL)
//	2011-03-03 22:49:49,497 [INFO ] net.pulseproject.mkinector.debugapp.misc.OscConnectionWindowGlue - onUserProcessing(user=UserImpl[id=1, uniqueId=0])
//	2011-03-03 22:49:54,096 [TRACE] net.pulseproject.mkinector.josceleton.gesture.internal.HitWallGestureImpl - doTrigger()
//	HitWallMidiSender: FIXMEEEEEEEEEE check values (expected start/end for high/low tunes) in MidiKinectorApp$HitWallMidiSender#onGestureCaptured(..)
//	2011-03-03 22:49:54,100 [INFO ] net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl - sendHitWallMidi(controllerValue=33)
//	2011-03-03 22:49:54,102 [DEBUG] net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl - fetching MIDI devices ...
//	2011-03-03 22:49:54,102 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - listMidiDeviceInfos()
//	2011-03-03 22:49:54,974 [TRACE] net.pulseproject.mkinector.josceleton.gesture.internal.HitWallGestureImpl - setting wasTriggered = false
//	2011-03-03 22:49:55,498 [TRACE] net.pulseproject.mkinector.josceleton.gesture.internal.HitWallGestureImpl - doTrigger()
//	HitWallMidiSender: FIXMEEEEEEEEEE check values (expected start/end for high/low tunes) in MidiKinectorApp$HitWallMidiSender#onGestureCaptured(..)
//	2011-03-03 22:49:55,501 [INFO ] net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl - sendHitWallMidi(controllerValue=19)
//	2011-03-03 22:49:55,501 [DEBUG] net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl - fetching MIDI devices ...
//	2011-03-03 22:49:55,501 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - listMidiDeviceInfos()
//	2011-03-03 22:49:55,532 [TRACE] net.pulseproject.mkinector.josceleton.gesture.internal.HitWallGestureImpl - doTrigger()
//	HitWallMidiSender: FIXMEEEEEEEEEE check values (expected start/end for high/low tunes) in MidiKinectorApp$HitWallMidiSender#onGestureCaptured(..)
//	2011-03-03 22:49:55,533 [INFO ] net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl - sendHitWallMidi(controllerValue=20)
//	2011-03-03 22:49:55,534 [DEBUG] net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl - fetching MIDI devices ...
//	2011-03-03 22:49:55,534 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - listMidiDeviceInfos()
//	2011-03-03 22:49:55,983 [DEBUG] net.pulseproject.commons.midi.MidiSystemStaticWrapper - listMidiDeviceInfos() ... returning 14 infos took 0.48 seconds.
//	2011-03-03 22:49:55,983 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - getMidiDevice(info=IAC Driver - Chrisi A)
//	2011-03-03 22:49:55,983 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - getMidiDevice(info=IAC Driver - Chrisi B)
//	2011-03-03 22:49:55,983 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - getMidiDevice(info=IAC Driver - Chrisi C)
//	2011-03-03 22:49:55,983 [INFO ] net.pulseproject.commons.midi.MidiSystemStaticWrapper - getMidiDevice(info=IAC Driver - Chrisi A)
//	2011-03-03 22:49:56,003 [DEBUG] net.pulseproject.commons.util.MidiUtil - Opening MIDI receiver for port [IAC Driver - Chrisi A] ...
//	Exception in thread "Thread-4" java.lang.ArrayIndexOutOfBoundsException: 6
//		at de.humatic.mmj.spi.CoreMidiProvider.getDeviceInfo(CoreMidiProvider.java:86)
//		at javax.sound.midi.MidiSystem.getMidiDeviceInfo(MidiSystem.java:173)
//		at net.pulseproject.commons.midi.MidiSystemStaticWrapper.listMidiDeviceInfos(MidiSystemStaticWrapper.java:34)
//		at net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl.checkOpenedReceiver(PlainSimpleMidiSenderImpl.java:64)
//		at net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl.sendMidiNote(PlainSimpleMidiSenderImpl.java:41)
//		at net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl.access$0(PlainSimpleMidiSenderImpl.java:39)
//		at net.pulseproject.mkinector.debugapp.misc.PlainSimpleMidiSenderImpl$1.run(PlainSimpleMidiSenderImpl.java:35)
//		at java.lang.Thread.run(Thread.java:680)
	
}
